// 封装 ajax
function ajax(options = {}) {
  const { url, method, async, data, token, dataType, success, error } = options

  // 1. 参数验证
  if (!url) {
    throw new Error('url 为必填选项 ^_^ !')
  }
  if (!(method === undefined || /^(get|post)$/i.test(method))) {
    throw new Error('目前只接受 GET 和 POST 请求方式, 请期待更新 O(∩_∩)O哈哈~ ')
  }
  if (!(async === undefined || typeof async === 'boolean')) {
    throw new Error('async 需要传递一个 布尔值 (#^.^#)')
  }
  if (!(data === undefined || typeof data === 'string')) {
    throw new Error('data 需要传递一个 字符串 类型')
  }
  if (!(token === undefined || typeof token === 'string')) {
    throw new Error('token 需要传递一个 字符串 类型')
  }
  if (!(dataType === undefined || /^(string|json)$/i.test(dataType))) {
    throw new Error('dataType 请传递一个 "string" 或者 "json"')
  }
  if (!(success === undefined || typeof success === 'function')) {
    throw new Error('success 需要传递一个 函数数据 类型')
  }
  if (!(error === undefined || typeof error === 'function')) {
    throw new Error('error 需要传递一个 函数数据 类型')
  }

  // 2. 准备一套默认值
  const _default = {
    url,
    method: method || 'GET',
    async: async ?? true,
    data: data || '',
    token: token || '',
    dataType: dataType || 'string',
    success: success || function () {},
    error: error || function () {}
  }
  if (/^get$/i.test(_default.method) && _default.data) {
    _default.url = _default.url + '?' + _default.data
  }

  // 3. 发送请求
  const xhr = new XMLHttpRequest()
  xhr.open(_default.method, _default.url, _default.async)
  xhr.onload = function () {
    if (_default.dataType === 'string') {
      _default.success(xhr.responseText)
      return
    }
    try {
      let result = JSON.parse(xhr.responseText)
      _default.success(result)
    } catch (err) {
      _default.error(err, xhr.responseText)
    }
  }
  if (_default.token) xhr.setRequestHeader('authorization', _default.token)
  if (/^post$/i.test(_default.method)) {
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
    xhr.send(_default.data)
  } else {
    xhr.send()
  }
}


// Promise 的形式封装 ajax
function pAjax(options = {}) {
  const p = new Promise(function (resolve, reject) {
    // 利用原先封装好的 ajax 函数来完成请求
    ajax({
      url: options.url,
      data: options.data,
      async: options.async,
      method: options.method,
      dataType: options.dataType,
      success (res) {
        resolve(res)
      },
      error (err, message) {
        reject(message)
      }
    })
  })

  return p
}
